package com.xunce.xcworkservice.exception;

import com.xunce.xcworkservice.response.ECode;
import com.xunce.xcworkservice.response.R;
import com.xunce.xcworkservice.response.ResultCode;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.ShiroException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Objects;

/**
 * @author yanlong
 * 异常拦截
 */
@RestControllerAdvice
@Slf4j
public class GlobalDefaultExceptionHandler {

    /**
     * 通用异常捕捉
     * */
    @ExceptionHandler(value = Exception.class)
    public R<String> handlerException(Exception e) {
        e.printStackTrace();
        log.error(e.getMessage(), (Object) e.getStackTrace());
        return  R.error(ECode.ERROR, e.getMessage());
    }

    /**
     * 权限验证类
     * */
    @ExceptionHandler(value = AuthorizationException.class)
    public R<String> handlerAuthorizationException(AuthorizationException e) {
        return R.error(ECode.NO_OPERATION_AUTHORITY, e.getMessage());
    }

    /**
     * 身份异常类
     * */
    @ExceptionHandler(value = ShiroException.class)
    public R<String> handlerShiroException(ShiroException e) {
        Integer code = ECode.UNAUTHORIZED;
        if(e instanceof AuthorizationException) {
            code = ECode.NO_OPERATION_AUTHORITY;
        }
        return R.error(code, e.getMessage());
    }

    /**
     * 自定义类型
     * */
    @ExceptionHandler(value = CustomException.class)
    public R<String> handlerCustomException(CustomException e) {
        if (e.getErrorCode() == 0){
            return R.error(e.getMessage());
        }
        return  R.error(e.getErrorCode(), e.getMessage());

    }

    /**
     * 请求方式不支持
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public R<String> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e) {
        return R.error(e.getMessage());
    }

    /**
     * 参数绑定
     */
    @ExceptionHandler(BindException.class)
    public R<String> handleBindException(BindException e) {
        String message = e.getAllErrors().get(0).getDefaultMessage();
        return R.error(ECode.VALID_ERROR, message);
    }

    /**
     * 参数验证
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public R<String> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        String message = Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage();
        return R.error(ECode.VALID_ERROR, message);
    }
}
